package com.junzhiit.nengji.shop.web.util;

import java.text.DecimalFormat;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bainaeco.framework.util.HttpClientUtils;

/**
 * 高德地图相关
 */
public class AmapUtil {

	private static Log logger = LogFactory.getLog(AmapUtil.class);

	/**
	 * 将非高德坐标转换为高德坐标
	 */
	public static Location convert(String value, String coordsys) {
		Location location = new Location(0.0,0.0);
		try {
			StringBuffer sb = new StringBuffer(Constants.AMAP_CONVERT_URL + "?");
			sb.append("locations=");
			sb.append(value);
			sb.append("&coordsys=");
			sb.append(coordsys);
			sb.append("&key=");
			sb.append(Constants.AMAP_SECRET_KEY);
			String result = HttpClientUtils.getMethodRequest(sb.toString());
			JSONObject json = (JSONObject) JSON.parse(result);
			if(json.get("status").toString().equals("1")){
				String locations = json.get("locations").toString();
				String src[] = locations.split(",");
				location.setLon(Double.parseDouble(src[0]));
				location.setLat(Double.parseDouble(src[1]));
				location.setLocation(locations);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		return location;
	}

	/**
	 * 此函数按照步行路径规划。返回最大所需时间和最大路程。
	 */
	public static JSONObject walking(Location current, Location target) {
		JSONObject resultObj = new JSONObject();
		try {
			StringBuffer sb = new StringBuffer(Constants.AMAP_WALK_URL + "?");
			sb.append("origin=");
			sb.append(current.getLocation());
			sb.append("&destination=");
			sb.append(target.getLocation());
			sb.append("&key=");
			sb.append(Constants.AMAP_SECRET_KEY);
			String result = HttpClientUtils.getMethodRequest(sb.toString());
			JSONObject json = (JSONObject) JSON.parse(result);
			Double maxDistance = new Double(-1);
			Double maxDuration = new Double(-1);
			if (json.get("status").toString().equals("1")) {
				JSONObject route = (JSONObject) json.get("route");
				JSONArray arr = (JSONArray) route.get("paths");
				for (int i = 0; i < arr.size(); i++) {
					JSONObject object = (JSONObject) arr.get(i);
					if (object.get("distance") != null && object.get("duration") != null) {
						Double distance = Double.parseDouble(object.get("distance").toString());
						Double duration = Double.parseDouble(object.get("duration").toString());
						if (distance > maxDistance) {
							maxDistance = distance;
						}
						if (duration > maxDuration) {
							maxDuration = duration;
						}
					}
				}
				resultObj.put("distance", formatDouble(maxDistance / 1000));
				resultObj.put("duration", (int) (maxDuration / 60));
			}else{
				resultObj.put("distance", maxDistance );
				resultObj.put("duration", maxDuration );
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		return resultObj;
	}

	/**
	 * 此函数按照驾车路径规划。返回最大所需时间和最大路程。
	 */
	public static JSONObject driving(Location current, Location target) {
		JSONObject resultObj = new JSONObject();
		try {
			StringBuffer sb = new StringBuffer(Constants.AMAP_DRIVE_URL + "?");
			sb.append("origin=");
			sb.append(current.getLocation());
			sb.append("&destination=");
			sb.append(target.getLocation());
			sb.append("&key=");
			sb.append(Constants.AMAP_SECRET_KEY);
			String result = HttpClientUtils.getMethodRequest(sb.toString());
			JSONObject json = (JSONObject) JSON.parse(result);
			Double maxDistance = new Double(-1);
			Double maxDuration = new Double(-1);
			if (json.get("status").toString().equals("1")) {
				JSONObject route = (JSONObject) json.get("route");
				JSONArray arr = (JSONArray) route.get("paths");
				for (int i = 0; i < arr.size(); i++) {
					JSONObject object = (JSONObject) arr.get(i);
					if (object.get("distance") != null && object.get("duration") != null) {
						Double distance = Double.parseDouble(object.get("distance").toString());
						Double duration = Double.parseDouble(object.get("duration").toString());
						if (distance > maxDistance) {
							maxDistance = distance;
						}
						if (duration > maxDuration) {
							maxDuration = duration;
						}
					}
				}
				resultObj.put("distance", formatDouble(maxDistance / 1000));
				resultObj.put("duration", (int) (maxDuration / 60));
			}else{
				resultObj.put("distance", maxDistance );
				resultObj.put("duration", maxDuration );
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		return resultObj;
	}

	/**
	 * 此函数按照骑行路径规划。返回最大所需时间和最大路程。
	 */
	public static JSONObject bicycling(Location current, Location target) {
		JSONObject resultObj = new JSONObject();
		try {
			StringBuffer sb = new StringBuffer(Constants.AMAP_RIDING_URL + "?");
			sb.append("origin=");
			sb.append(current.getLocation());
			sb.append("&destination=");
			sb.append(target.getLocation());
			sb.append("&key=");
			sb.append(Constants.AMAP_SECRET_KEY);
			String result = HttpClientUtils.getMethodRequest(sb.toString());
			JSONObject json = (JSONObject) JSON.parse(result);
			Double maxDistance = new Double(-1);
			Double maxDuration = new Double(-1);
			if (json.get("errcode").toString().equals("0")) {
				JSONObject route = (JSONObject) json.get("data");
				JSONArray arr = (JSONArray) route.get("paths");
				for (int i = 0; i < arr.size(); i++) {
					JSONObject object = (JSONObject) arr.get(i);
					if (object.get("distance") != null && object.get("duration") != null) {
						Double distance = Double.parseDouble(object.get("distance").toString());
						Double duration = Double.parseDouble(object.get("duration").toString());
						if (distance > maxDistance) {
							maxDistance = distance;
						}
						if (duration > maxDuration) {
							maxDuration = duration;
						}
					}
				}
				resultObj.put("distance", formatDouble(maxDistance / 1000));
				resultObj.put("duration", (int) (maxDuration / 60));
			}else{
				resultObj.put("distance", maxDistance );
				resultObj.put("duration", maxDuration );
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		return resultObj;
	}

	/**
	 * 此函数按照两点之间最大距离计算。返回最大距离(米)、最大时间(秒),如果不指定默认交通类型。 0：直线距离（没有最大时间返回）
	 * 1：驾车导航距离（仅支持国内坐标）。 2：公交规划距离（仅支持同城坐标,QPS不可超过1，否则可能导致意外）
	 * 3：步行规划距离（仅支持5km之间的距离）
	 */
	public static JSONObject distanceMeasurement(Location current, Location target, Integer type) {
		JSONObject resultObj = new JSONObject();
		try {
			StringBuffer sb = new StringBuffer(Constants.AMAP_DISTANCE_URL + "?");
			sb.append("origins=");
			sb.append(current.getLocation());
			sb.append("&destination=");
			sb.append(target.getLocation());
			sb.append("&type=");
			sb.append(type);
			sb.append("&key=");
			sb.append(Constants.AMAP_SECRET_KEY);
			String result = HttpClientUtils.getMethodRequest(sb.toString());
			JSONObject json = (JSONObject) JSON.parse(result);
			Double maxDistance = new Double(-1);
			Double maxDuration = new Double(-1);
			if (json.get("status").equals("1")) {
				JSONArray arr = (JSONArray) json.get("results");
				for (int i = 0; i < arr.size(); i++) {
					JSONObject object = (JSONObject) arr.get(i);
					if (object.get("distance") != null && object.get("duration") != null) {
						Double distance = Double.parseDouble(object.get("distance").toString());
						Double duration = Double.parseDouble(object.get("duration").toString());
						if (distance > maxDistance) {
							maxDistance = distance;
						}
						if (duration > maxDuration) {
							maxDuration = duration;
						}
					}
				}
				resultObj.put("distance", formatDouble(maxDistance / 1000));
				resultObj.put("duration", (int) (maxDuration / 60));
			}else{
				resultObj.put("distance", maxDistance );
				resultObj.put("duration", maxDuration );
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		return resultObj;
	}

	/**
	 * 此函数取得地址的经纬度。
	 */
	public static Location latitudeLongitude(String address) {
		Location loc = new Location(address);
		try {
			StringBuffer sb = new StringBuffer(Constants.AMAP_GEO_CODING + "?");
			sb.append("address=");
			sb.append(address);
			sb.append("&output=JSON");
			sb.append("&key=");
			sb.append(Constants.AMAP_SECRET_KEY);
			String result = HttpClientUtils.getMethodRequest(sb.toString());
			JSONObject json = (JSONObject) JSON.parse(result);
			if (json.get("status").toString().equals("1")) {
				JSONArray arr = (JSONArray) json.get("geocodes");
				if (arr.size() > 0) {
					JSONObject par = (JSONObject) arr.get(0);
					String location = (String) par.get("location");
					if (location != null && !location.equals("")) {
						String src[] = location.split(",");
						loc.setLon(Double.parseDouble(src[0]));
						loc.setLat(Double.parseDouble(src[1]));
					}
					loc.setLocation(location);
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		return loc;
	}

	private static String formatDouble(double number) {
		String moneyStr = String.valueOf(number);
		String[] num = moneyStr.split("\\.");
		if (num.length == 2) {
			if (Integer.parseInt(num[1]) > 0) {
				return new DecimalFormat("#.##").format(number);
			} else {
				return num[0];
			}
		} else {
			return num[0];
		}
	}

	public static class Location {
		private Double lon;
		private Double lat;
		private String location;
		private String address;

		public Location(Double lon, Double lat) {
			this.lon = lon;
			this.lat = lat;
		}

		public Location(String address) {
			this.address = address;
		}

		public Double getLon() {
			return lon;
		}

		public void setLon(Double lon) {
			this.lon = lon;
		}

		public Double getLat() {
			return lat;
		}

		public void setLat(Double lat) {
			this.lat = lat;
		}

		public String getAddress() {
			return address;
		}

		public void setAddress(String address) {
			this.address = address;
		}

		public String getLocation() {
			return location;
		}

		public void setLocation(String location) {
			this.location = location;
		}

		@Override
		public String toString() {
			return "longitude[" + this.lon + "],latitude[" + this.lat + "],address:" + this.address;
		}
	}
}
